home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Diamond Collection / The Diamond Collection (Software Vault)(Digital Impact).ISO / cdr13 / gc0165.zip / RTFACTN.C < prev    next >
C/C++ Source or Header  |  1993-11-19  |  11KB  |  315 lines

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stddef.h>
  4. #include <ctype.h>
  5. #include "rtftype.h"
  6. #include "rtfdecl.h"
  7.  
  8. // RTF parser tables
  9.  
  10. // Property descriptions
  11. PROP rgprop [ipropMax] = {
  12.     actnByte,   propChp,    offsetof(CHP, fBold),       // ipropBold
  13.     actnByte,   propChp,    offsetof(CHP, fItalic),     // ipropItalic
  14.     actnByte,   propChp,    offsetof(CHP, fUnderline),  // ipropUnderline
  15.     actnWord,   propPap,    offsetof(PAP, xaLeft),      // ipropLeftInd
  16.     actnWord,   propPap,    offsetof(PAP, xaRight),     // ipropRightInd
  17.     actnWord,   propPap,    offsetof(PAP, xaFirst),     // ipropFirstInd
  18.     actnWord,   propSep,    offsetof(SEP, cCols),       // ipropCols
  19.     actnWord,   propSep,    offsetof(SEP, xaPgn),       // ipropPgnX
  20.     actnWord,   propSep,    offsetof(SEP, yaPgn),       // ipropPgnY
  21.     actnWord,   propDop,    offsetof(DOP, xaPage),      // ipropXaPage
  22.     actnWord,   propDop,    offsetof(DOP, yaPage),      // ipropYaPage
  23.     actnWord,   propDop,    offsetof(DOP, xaLeft),      // ipropXaLeft
  24.     actnWord,   propDop,    offsetof(DOP, xaRight),     // ipropXaRight
  25.     actnWord,   propDop,    offsetof(DOP, yaTop),       // ipropYaTop
  26.     actnWord,   propDop,    offsetof(DOP, yaBottom),    // ipropYaBottom
  27.     actnWord,   propDop,    offsetof(DOP, pgnStart),    // ipropPgnStart
  28.     actnByte,   propSep,    offsetof(SEP, sbk),         // ipropSbk
  29.     actnByte,   propSep,    offsetof(SEP, pgnFormat),   // ipropPgnFormat
  30.     actnByte,   propDop,    offsetof(DOP, fFacingp),    // ipropFacingp
  31.     actnByte,   propDop,    offsetof(DOP, fLandscape),  // ipropLandscape
  32.     actnByte,   propPap,    offsetof(PAP, just),        // ipropJust
  33.     actnSpec,   propPap,    0,                          // ipropPard
  34.     actnSpec,   propChp,    0,                          // ipropPlain
  35.     actnSpec,   propSep,    0,                          // ipropSectd
  36. };
  37.  
  38. // Keyword descriptions
  39. SYM rgsymRtf[] = {
  40. //  keyword     dflt    fPassDflt   kwd         idx
  41.     "b",        1,      fFalse,     kwdProp,    ipropBold,
  42.     "u",        1,      fFalse,     kwdProp,    ipropUnderline,
  43.     "i",        1,      fFalse,     kwdProp,    ipropItalic,
  44.     "li",       0,      fFalse,     kwdProp,    ipropLeftInd,
  45.     "ri",       0,      fFalse,     kwdProp,    ipropRightInd,
  46.     "fi",       0,      fFalse,     kwdProp,    ipropFirstInd,
  47.     "cols",     1,      fFalse,     kwdProp,    ipropCols,
  48.     "sbknone",  sbkNon, fTrue,      kwdProp,    ipropSbk,
  49.     "sbkcol",   sbkCol, fTrue,      kwdProp,    ipropSbk,
  50.     "sbkeven",  sbkEvn, fTrue,      kwdProp,    ipropSbk,
  51.     "sbkodd",   sbkOdd, fTrue,      kwdProp,    ipropSbk,
  52.     "sbkpage",  sbkPg,  fTrue,      kwdProp,    ipropSbk,
  53.     "pgnx",     0,      fFalse,     kwdProp,    ipropPgnX,
  54.     "pgny",     0,      fFalse,     kwdProp,    ipropPgnY,
  55.     "pgndec",   pgDec,  fTrue,      kwdProp,    ipropPgnFormat,
  56.     "pgnucrm",  pgURom, fTrue,      kwdProp,    ipropPgnFormat,
  57.     "pgnlcrm",  pgLRom, fTrue,      kwdProp,    ipropPgnFormat,
  58.     "pgnucltr", pgULtr, fTrue,      kwdProp,    ipropPgnFormat,
  59.     "pgnlcltr", pgLLtr, fTrue,      kwdProp,    ipropPgnFormat,
  60.     "qc",       justC,  fTrue,      kwdProp,    ipropJust,
  61.     "ql",       justL,  fTrue,      kwdProp,    ipropJust,
  62.     "qr",       justR,  fTrue,      kwdProp,    ipropJust,
  63.     "qj",       justF,  fTrue,      kwdProp,    ipropJust,
  64.     "paperw",   12240,  fFalse,     kwdProp,    ipropXaPage,
  65.     "paperh",   15480,  fFalse,     kwdProp,    ipropYaPage,
  66.     "margl",    1800,   fFalse,     kwdProp,    ipropXaLeft,
  67.     "margr",    1800,   fFalse,     kwdProp,    ipropXaRight,
  68.     "margt",    1440,   fFalse,     kwdProp,    ipropYaTop,
  69.     "margb",    1440,   fFalse,     kwdProp,    ipropYaBottom,
  70.     "pgnstart", 1,      fTrue,      kwdProp,    ipropPgnStart,
  71.     "facingp",  1,      fTrue,      kwdProp,    ipropFacingp,
  72.     "landscape",1,      fTrue,      kwdProp,    ipropLandscape,
  73.     "par",      0,      fFalse,     kwdChar,    0x0a,
  74.     "\0x0a",    0,      fFalse,     kwdChar,    0x0a,
  75.     "\0x0d",    0,      fFalse,     kwdChar,    0x0a,
  76.     "tab",      0,      fFalse,     kwdChar,    0x09,
  77.     "ldblquote",0,      fFalse,     kwdChar,    '"',
  78.     "rdblquote",0,      fFalse,     kwdChar,    '"',
  79.     "bin",      0,      fFalse,     kwdSpec,    ipfnBin,
  80.     "*",        0,      fFalse,     kwdSpec,    ipfnSkipDest,
  81.     "'",        0,      fFalse,     kwdSpec,    ipfnHex,
  82.     "author",   0,      fFalse,     kwdDest,    idestSkip,
  83.     "buptim",   0,      fFalse,     kwdDest,    idestSkip,
  84.     "colortbl", 0,      fFalse,     kwdDest,    idestSkip,
  85.     "comment",  0,      fFalse,     kwdDest,    idestSkip,
  86.     "creatim",  0,      fFalse,     kwdDest,    idestSkip,
  87.     "doccomm",  0,      fFalse,     kwdDest,    idestSkip,
  88.     "fonttbl",  0,      fFalse,     kwdDest,    idestSkip,
  89.     "footer",   0,      fFalse,     kwdDest,    idestSkip,
  90.     "footerf",  0,      fFalse,     kwdDest,    idestSkip,
  91.     "footerl",  0,      fFalse,     kwdDest,    idestSkip,
  92.     "footerr",  0,      fFalse,     kwdDest,    idestSkip,
  93.     "footnote", 0,      fFalse,     kwdDest,    idestSkip,
  94.     "ftncn",    0,      fFalse,     kwdDest,    idestSkip,
  95.     "ftnsep",   0,      fFalse,     kwdDest,    idestSkip,
  96.     "ftnsepc",  0,      fFalse,     kwdDest,    idestSkip,
  97.     "header",   0,      fFalse,     kwdDest,    idestSkip,
  98.     "headerf",  0,      fFalse,     kwdDest,    idestSkip,
  99.     "headerl",  0,      fFalse,     kwdDest,    idestSkip,
  100.     "headerr",  0,      fFalse,     kwdDest,    idestSkip,
  101.     "info",     0,      fFalse,     kwdDest,    idestSkip,
  102.     "keywords", 0,      fFalse,     kwdDest,    idestSkip,
  103.     "operator", 0,      fFalse,     kwdDest,    idestSkip,
  104.     "pict",     0,      fFalse,     kwdDest,    idestSkip,
  105.     "printim",  0,      fFalse,     kwdDest,    idestSkip,
  106.     "private1", 0,      fFalse,     kwdDest,    idestSkip,
  107.     "revtim",   0,      fFalse,     kwdDest,    idestSkip,
  108.     "rxe",      0,      fFalse,     kwdDest,    idestSkip,
  109.     "stylesheet",   0,      fFalse,     kwdDest,    idestSkip,
  110.     "subject",  0,      fFalse,     kwdDest,    idestSkip,
  111.     "tc",       0,      fFalse,     kwdDest,    idestSkip,
  112.     "title",    0,      fFalse,     kwdDest,    idestSkip,
  113.     "txe",      0,      fFalse,     kwdDest,    idestSkip,
  114.     "xe",       0,      fFalse,     kwdDest,    idestSkip,
  115.     "{",        0,      fFalse,     kwdChar,    '{',
  116.     "}",        0,      fFalse,     kwdChar,    '}',
  117.     "\\",       0,      fFalse,     kwdChar,    '\\'
  118.     };
  119. int isymMax = sizeof(rgsymRtf) / sizeof(SYM);
  120.  
  121. //
  122. // %%Function: ecApplyPropChange
  123. //
  124. // Set the property identified by _iprop_ to the value _val_.
  125. //
  126. //
  127.  
  128. int
  129. ecApplyPropChange(IPROP iprop, int val)
  130. {
  131.     char *pb;
  132.  
  133.     if (rds == rdsSkip)                 // If we're skipping text,
  134.         return ecOK;                    // don't do anything.
  135.  
  136.     switch (rgprop[iprop].prop)
  137.     {
  138.     case propDop:
  139.         pb = (char *)&dop;
  140.         break;
  141.     case propSep:
  142.         pb = (char *)&sep;
  143.         break;
  144.     case propPap:
  145.         pb = (char *)&pap;
  146.         break;
  147.     case propChp:
  148.         pb = (char *)&chp;
  149.         break;
  150.     default:
  151.         if (rgprop[iprop].actn != actnSpec)
  152.             return ecBadTable;
  153.         break;
  154.     }
  155.     switch (rgprop[iprop].actn)
  156.     {
  157.     case actnByte:
  158.         pb[rgprop[iprop].offset] = (unsigned char) val;
  159.         break;
  160.     case actnWord:
  161.         (*(int *) (pb+rgprop[iprop].offset)) = val;
  162.         break;
  163.     case actnSpec:
  164.         return ecParseSpecialProperty(iprop, val);
  165.         break;
  166.     default:
  167.         return ecBadTable;
  168.     }
  169.     return ecOK;
  170. }
  171.  
  172. //
  173. // %%Function: ecParseSpecialProperty
  174. //
  175. // Set a property that requires code to evaluate.
  176. //
  177.  
  178. int
  179. ecParseSpecialProperty(IPROP iprop, int val)
  180. {
  181.     switch (iprop)
  182.     {
  183.     case ipropPard:
  184.         memset(&pap, 0, sizeof(pap));
  185.         return ecOK;
  186.     case ipropPlain:
  187.         memset(&chp, 0, sizeof(chp));
  188.         return ecOK;
  189.     case ipropSectd:
  190.         memset(&sep, 0, sizeof(sep));
  191.         return ecOK;
  192.     default:
  193.         return ecBadTable;
  194.     }
  195.     return ecBadTable;
  196. }
  197.  
  198. //
  199. // %%Function: ecTranslateKeyword.
  200. //
  201. // Step 3.
  202. // Search rgsymRtf for szKeyword and evaluate it appropriately.
  203. //
  204. // Inputs:
  205. // szKeyword:   The RTF control to evaluate.
  206. // param:       The parameter of the RTF control.
  207. // fParam:      fTrue if the control had a parameter; (i.e., if param is valid)
  208. //              fFalse if it did not.
  209. //
  210.  
  211. int
  212. ecTranslateKeyword(char *szKeyword, int param, bool fParam)
  213. {
  214.     int isym;
  215.  
  216.     // search for szKeyword in rgsymRtf
  217.  
  218.     for (isym = 0; isym < isymMax; isym++)
  219.         if (strcmp(szKeyword, rgsymRtf[isym].szKeyword) == 0)
  220.             break;
  221.     if (isym == isymMax)            // control word not found
  222.     {
  223.         if (fSkipDestIfUnk)         // if this is a new destination
  224.             rds = rdsSkip;          // skip the destination
  225.                                     // else just discard it
  226.         fSkipDestIfUnk = fFalse;
  227.         return ecOK;
  228.     }
  229.  
  230.     // found it!  use kwd and idx to determine what to do with it.
  231.  
  232.     fSkipDestIfUnk = fFalse;
  233.     switch (rgsymRtf[isym].kwd)
  234.     {
  235.     case kwdProp:
  236.         if (rgsymRtf[isym].fPassDflt || !fParam)
  237.             param = rgsymRtf[isym].dflt;
  238.         return ecApplyPropChange(rgsymRtf[isym].idx, param);
  239.     case kwdChar:
  240.         return ecParseChar(rgsymRtf[isym].idx);
  241.     case kwdDest:
  242.         return ecChangeDest(rgsymRtf[isym].idx);
  243.     case kwdSpec:
  244.         return ecParseSpecialKeyword(rgsymRtf[isym].idx);
  245.     default:
  246.         return ecBadTable;
  247.     }
  248.     return ecBadTable;
  249. }
  250.  
  251. //
  252. // %%Function: ecChangeDest
  253. //
  254. // Change to the destination specified by idest.
  255. // There's usually more to do here than this...
  256. //
  257.  
  258. int
  259. ecChangeDest(IDEST idest)
  260. {
  261.     if (rds == rdsSkip)             // if we're skipping text,
  262.         return ecOK;                // don't do anything
  263.  
  264.     switch (idest)
  265.     {
  266.     default:
  267.         rds = rdsSkip;              // when in doubt, skip it...
  268.         break;
  269.     }
  270.     return ecOK;
  271. }
  272.  
  273. //
  274. // %%Function: ecEndGroupAction
  275. //
  276. // The destination specified by rds is coming to a close.
  277. // If there's any cleanup that needs to be done, do it now.
  278. //
  279.  
  280. int
  281. ecEndGroupAction(RDS rds)
  282. {
  283.     return ecOK;
  284. }
  285.  
  286. //
  287. // %%Function: ecParseSpecialKeyword
  288. //
  289. // Evaluate an RTF control that needs special processing.
  290. //
  291.  
  292. int
  293. ecParseSpecialKeyword(IPFN ipfn)
  294. {
  295.     if (rds == rdsSkip && ipfn != ipfnBin)  // if we're skipping, and it's not
  296.         return ecOK;                        // the \bin keyword, ignore it.
  297.     switch (ipfn)
  298.     {
  299.     case ipfnBin:
  300.         ris = risBin;
  301.         cbBin = lParam;
  302.         break;
  303.     case ipfnSkipDest:
  304.         fSkipDestIfUnk = fTrue;
  305.         break;
  306.     case ipfnHex:
  307.      ris = risHex;
  308.      break;
  309.     default:
  310.         return ecBadTable;
  311.     }
  312.     return ecOK;
  313. }
  314.  
  315.